﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace NigLib
{
    public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

    public static class WinAPIs
    {
        //----------------kernel32.dll-------------------------
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        [DllImport("user32.dll")]
        public static extern UInt32 SendInput(UInt32 nInputs, ApiInput64[] pInputs, int cbSize);

        [DllImport("kernel32.dll")]
        public static extern int GetTickCount();

        //----------------user32.dll---------------------------
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(HookType idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ApiPoint
    {
        public int X;
        public int Y;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MouseHookStruct
    {
        public ApiPoint Location;
        public int hwnd;
        public int wHitTestCode;
        public int dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct KeyboardHookStruct
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct ApiInput
    {
        [FieldOffset(0)]
        public Int32 type;
        [FieldOffset(4)]
        public KeyBoardInput ki;
        [FieldOffset(4)]
        public MouseInput mi;
        [FieldOffset(4)]
        public HardwareInput hi;
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct ApiInput64
    {
        [FieldOffset(0)]
        public Int64 type;
        [FieldOffset(8)]
        public KeyBoardInput ki;
        [FieldOffset(8)]
        public MouseInput mi;
        [FieldOffset(8)]
        public HardwareInput hi;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MouseInput
    {
        public Int32 dx;
        public Int32 dy;
        public Int32 mouseData;
        public Int32 dwFlags;
        public Int32 time;
        public IntPtr dwExtraInfo;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct KeyBoardInput
    {
        public Int16 wVk;
        public Int16 wScan;
        public Int32 dwFlags;
        public Int32 time;
        public IntPtr dwExtraInfo;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct HardwareInput
    {
        public Int32 uMsg;
        public Int16 wParamL;
        public Int16 wParamH;
    }

    //-----------------------------------------------------------------------------
    /// <summary>
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
    /// </summary>
    //-----------------------------------------------------------------------------
    public enum InputType
    {
        INPUT_MOUSE = 0,
        INPUT_KEYBOARD = 1,
        INPUT_HARDWARE = 2,
    }

    //-----------------------------------------------------------------------------
    /// <summary>
    /// http://msdn.microsoft.com/library/windows/desktop/ms644990.aspx
    /// </summary>
    //-----------------------------------------------------------------------------
    public enum HookType
    {
        WH_MSGFILTER = -1,
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14,
    }

    //-----------------------------------------------------------------------------
    /// <summary>
    /// http://msdn.microsoft.com/zh-cn/library/ms644927(en-us,VS.85).aspx#system_defined
    /// </summary>
    //-----------------------------------------------------------------------------
    public enum WinMessage
    {
        //mouse msg
        WM_MOUSEMOVE = 0x0200,
        WM_LBUTTONDOWN = 0x0201,
        WM_LBUTTONUP = 0x0202,
        WM_LBUTTONDBLCLK = 0x0203,
        WM_RBUTTONDOWN = 0x0204,
        WM_RBUTTONUP = 0x0205,
        WM_RBUTTONDBLCLK = 0x0206,

        //keyboard msg
        WM_KEYUP = 0x0101,
        WM_KEYDOWN = 0x0100,
    }
}
